package it.hive.controller;

import it.hive.controller.download.DownloadGUI;
import it.hive.mediaplayer.MediaPlayerController;
import it.hive.mediaplayer.beans.impl.Traccia;
import it.hive.mediaplayer.properties.MediaPlayerProperties;
import it.hive.model.Application;
import it.hive.model.common.ApplicationProperties;
import it.hive.model.common.constants.M2O_Default;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Pane;

import org.apache.commons.lang3.StringUtils;

/**
 * 
 * @author 04400099
 */
public class HomeController implements Initializable {
	private volatile MediaPlayerController mediaPlayerController;
	private Application application;

	@FXML
	private volatile Label label;
	@FXML
	private volatile Pane mediaPanel;
	@FXML
	private volatile Button play;
	@FXML
	private volatile Button stop;
	@FXML
	private volatile Button pausa;
	@FXML
	private volatile Button branoSucc;
	@FXML
	private volatile Button branoPrec;
	@FXML
	private volatile ToggleButton muto;
	@FXML
	private volatile Button download;
	@FXML
	private volatile ProgressBar barraAvanzamento;
	@FXML
	private volatile ProgressIndicator percentualeBuffer;
	@FXML
	private volatile ProgressIndicator percentualeDownload;
	@FXML
	private Slider volume;

	private double volumeAnteMuto;

	@Override
	public void initialize(URL url, ResourceBundle rb) {
		application = Application.getIstanza();
		mediaPlayerController = MediaPlayerController.getMediaPlayerController();
		volume.setMin(0);
		volume.setMax(1);
		MediaPlayerProperties.volumeProperty.bind(volume.valueProperty());
		play.disableProperty()
				.bind(MediaPlayerProperties.onPlaying.and(MediaPlayerProperties.tracciaInRiproduzione
						.isEqualTo(ApplicationProperties.currentSelectedTrack)));
		muto.selectedProperty().addListener(new ChangeListener<Boolean>() {
			@Override
			public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
				if (muto.isSelected()) {
					volumeAnteMuto = volume.getValue();
					volume.setValue(0);
				} else {
					volume.setValue(volumeAnteMuto);
				}

			}
		});
		barraAvanzamento.progressProperty().bindBidirectional(MediaPlayerProperties.playProgress);
		barraAvanzamento.visibleProperty().bindBidirectional(MediaPlayerProperties.onPlaying);
		percentualeBuffer.progressProperty().bindBidirectional(MediaPlayerProperties.playBufferProperty);
		label.textProperty().bindBidirectional(MediaPlayerProperties.playTimeProgress);
		percentualeBuffer.visibleProperty().bindBidirectional(MediaPlayerProperties.onBuffering);
		download.visibleProperty().bind(ApplicationProperties.currentSelectedTrack.isNotNull().and(ApplicationProperties.downloadInCorso.not()));
		percentualeDownload.visibleProperty().bind(ApplicationProperties.downloadInCorso);
		percentualeDownload.progressProperty().bind(ApplicationProperties.percentualeDownload);
	}

	@FXML
	private void play(ActionEvent event) {
		riproduciBrano();
	}

	@FXML
	private void stop(ActionEvent event) {
		if (mediaPlayerController != null) {
			mediaPlayerController.stop();
		}
	}

	@FXML
	private void pausa(ActionEvent event) {
		if (mediaPlayerController.getMediaPlayer() != null) {
			mediaPlayerController.pause();
		}
	}

	@FXML
	private void next(ActionEvent event) {
		MediaController.selectNext();
		riproduciBrano();
	}

	@FXML
	private void prev(ActionEvent event) {
		MediaController.selectPrevious();
		riproduciBrano();
	}

	@FXML
	private void download(ActionEvent event) {
		Traccia traccia = ApplicationProperties.currentSelectedTrack.get();
		if (M2O_Default.TRACCIA_STREAMING.equals(traccia)) {
			ApplicationProperties.downloadInCorso.set(true);
			return;
		}
		DownloadGUI.scaricaTraccia(traccia);
	}

	private void riproduciBrano() {
		Traccia traccia = ApplicationProperties.currentSelectedTrack.get();
		if (traccia != null) {
			if (traccia.isUnparsed()) {
				application.risolviURL(traccia);
			}
			mediaPlayerController.play(traccia);
			mediaPlayerController.getMediaPlayer().setOnEndOfMedia(new Runnable() {
				@Override
				public void run() {
					next(null);
				}
			});
		}
	}

	@FXML
	ImageView streaming;

	@FXML
	public void streaming(MouseEvent event) {
		ApplicationProperties.currentSelectedTrack.set(M2O_Default.TRACCIA_STREAMING);
	}

	@FXML
	public void streamingRDF(MouseEvent event) {
		ApplicationProperties.currentSelectedTrack.set(M2O_Default.TRACCIA_STREAMING_RDF);
	}

	@FXML
	private TextField streamingUrl;

	@FXML
	public void streamingURL(ActionEvent event) {
		if (StringUtils.isNotBlank(streamingUrl.getText())) {
			try {
				ApplicationProperties.currentSelectedTrack.set(new Traccia(new URL(streamingUrl.getText()), null, "Streaming"));
				riproduciBrano();
			} catch (IOException | NullPointerException e) {
				streamingUrl.setText("ERRORE - verificare che l'URL sia corretto");
				streamingUrl.selectAll();
			}
		}
	}

	public void playStreaming(MouseEvent event) {
		riproduciBrano();
	}

	@FXML
	public void progressClick(MouseEvent event) {
		mediaPlayerController.seek(event.getX() / barraAvanzamento.getWidth());
	}

	@FXML
	public void scrollVolume(ScrollEvent event) {
		double segno = 1;
		if (event.getDeltaY() < 0) {
			segno = -1;
		}
		double vol = volume.getValue();
		if (vol > 0 || vol < 1) {
			volume.setValue(vol + (0.1 * segno));
		}
	}
}
